package com.ht.api.call.func.impl.kf;

import javax.sql.DataSource;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import com.ht.api.bean.AjaxResult;
import com.ht.api.bean.LoginBean;
import com.ht.api.call.func.IFunctionCall;
import com.ht.api.constant.KfSessionStatus;
import com.ht.api.constant.Message;
import com.ht.api.db.Db;
import com.ht.api.db.Entity;
import com.ht.api.db.Mapper;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.util.HtUtil;
import com.ht.api.websocket.WebSocket;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 转接会话
 * @author asq
 * @createTime 2025年3月17日 10:41:36
 */
@Slf4j
public class KfSessionTransferFunctionCall implements IFunctionCall {
	/** 锁 */
	private RedissonClient redissonClient = SpringUtil.getBean(RedissonClient.class);
    
    private WebSocket webSocket;

	@Override
	public String getName() {
		return "转接会话";
	}

	@Override
	public JSONObject execute(LoginBean me, JSONObject param, AjaxResult result) {
		// 获取登陆用户的数据源
		DataSource ds = me.getDataSource();
		
		// 查询会话
		String sessionId = param.getStr("main_id");
		String userid = param.getStr("userid");
		Entity kfSession = Db.createSqlParser("kf_session").findById(ds, sessionId);
		if (kfSession == null) {
			throw new HtException("会话main_id不存在：" + sessionId);
		}
		if (KfSessionStatus.PROGRESS != kfSession.getInt("status")) {
			throw new HtException("只能转接”接待中“的会话！");
		}
		if (userid.equals(kfSession.getStr("userid"))) {
			throw new HtException("不能转接给自己！");
		}
		
		// 加锁
		RLock lock = redissonClient.getLock(sessionId);
		if (lock.tryLock()) {
			try {
				// 记录旧接待人员
				String oldUserid = kfSession.getStr("userid");
				
				// 设置新的接待人员
				kfSession.set("userid", userid);
				Db.insert(ds, kfSession);

				// 结束旧人员的会话与客服关联
				Entity kfSessionServicerRelationEntity = Db.createSqlParser("kf_session_servicer_relation")
						.where("session_id", sessionId).order("start_time", "desc").limit(1).findOne(ds);
				if (kfSessionServicerRelationEntity != null) {
					Entity kfSessionServicerRelationOld = Entity.create("kf_session_servicer_relation");
					kfSessionServicerRelationOld.setMainId(kfSessionServicerRelationEntity.getMainId());
					kfSessionServicerRelationOld.set("end_time", DateUtil.now());
					kfSessionServicerRelationOld.set("status", 1);
					Db.insert(ds, kfSessionServicerRelationOld);
				}

				// 开始新人员的会话与客服关联
				Entity kfSessionServicerRelationNew = Entity.create("kf_session_servicer_relation");
				kfSessionServicerRelationNew.set("session_id", sessionId);
				kfSessionServicerRelationNew.set("userid", userid);
				kfSessionServicerRelationNew.set("start_time", DateUtil.now());
				kfSessionServicerRelationNew.set("status", 0);
				kfSessionServicerRelationNew.set("source", 2); // 转接
				kfSessionServicerRelationNew.set("source_id", oldUserid);
				Db.insert(ds, kfSessionServicerRelationNew);
				
				// 创建一条会话转接的系统消息
				createMsg(ds, kfSession, oldUserid, userid);
				
				// 给新接待人员推送会话
				Mapper.translate(ds, kfSession);
				getWebSocket().sendMessage(Message.createMsg(Message.SESSION, kfSession), userid);
			} catch (Exception e) {
				log.error("[KfSessionOverFunctionCall]转接会话时发生异常：{}", e.getMessage(), e);
			} finally {
				if (lock.isHeldByCurrentThread()) {
					lock.unlock();
				}}
		} else {
			log.info("[KfSessionOverFunctionCall]未获取到锁，忽略调用。main_id:{}", sessionId);
		}

		return JSONUtil.createObj();
	}
	
	/**
	 * 创建一条转接消息
	 * @param ds
	 * @param kfSession 转接后的会话
	 * @param oldUserid 旧的接待人员userid
	 * @param oldLoginId 旧的接待人员loginid
	 */
	private void createMsg(DataSource ds, Entity kfSession, String oldUserid, String oldLoginId) {
		String oldUserName = getAliasByUserid(ds, oldUserid);
		String newUserName = getAliasByUserid(ds, kfSession.getStr("userid"));
		
		// 创建一条转接消息
		Entity kfMessage = Db.createEntity("kf_message");
		kfMessage.set("msgid", HtUtil.getId());
		kfMessage.set("open_kfid", kfSession.getStr("open_kfid"));
		kfMessage.set("openid", kfSession.getStr("external_userid"));
		kfMessage.set("userid", kfSession.getStr("userid"));
		kfMessage.set("send_time", DateUtil.now());
		kfMessage.set("origin", 4);
		kfMessage.set("msgtype", "text");
		kfMessage.set("content", String.format("%s将会话转接给%s", oldUserName, newUserName));
		kfMessage.set("appid", kfSession.getStr("appid"));
		Db.insert(ds, kfMessage);

		// 推送给转接人
		getWebSocket().sendMessage(Message.createMsg(Message.MESSAGE, kfMessage), oldLoginId);
	}
	
	/**
	 * 查询接待人员名称
	 * @param ds
	 * @param userid
	 * @return
	 */
	private String getAliasByUserid(DataSource ds, String userid) {
		Entity user = Db.createSqlParser("sys_user").findById(userid);
		if (user != null) {
			String name = user.getStr("user_name");
			String desplayName = null;
			if (StrUtil.isNotBlank(name)) {
				desplayName = name;
			} else {
				desplayName = "未命名接待人员";
			}
			
			
			return String.format("[%s]", desplayName);
		} else {
			return "[未知接待人员]";
		}
	}
    
    /**
     * 获取websocket对象
     * @return
     */
    private WebSocket getWebSocket() {
    	if (webSocket == null) {
    		webSocket = SpringUtil.getBean(WebSocket.class);
    	}
    	return webSocket;
    }

}
